using SocketPorxyServer;
using SuperSocket.Channel;
using SuperSocket.Command;

namespace SuperSocketProxy.Commands;

public abstract class SocketProxyAsyncCommand<TPacket> : IAsyncCommand<SocketProxySession, SocketProxyPacket> 
    where TPacket : SocketProxyPacket
{
    protected abstract ValueTask ExecuteAsync(SocketProxySession session, TPacket package);
    
    public async ValueTask ExecuteAsync(SocketProxySession session, SocketProxyPacket package)
    {
        try
        {
            await ExecuteAsync(session, (TPacket)package);
        }
        catch (CloseSessionException)
        {
            await session.CloseAsync(CloseReason.ProtocolError);
        }
        catch (Exception)
        {
            await session.CloseAsync(CloseReason.ApplicationError);
        }
    }
}

public abstract class SocketProxyPacketAsyncCommand<TPacket> : IAsyncCommand<SocketProxySession, SocketProxyPacket> 
    where TPacket : SocketProxyPacket
{
    protected abstract ValueTask ExecuteAsync(SocketProxySession session, TPacket package, IPacketResponse response);
    
    public async ValueTask ExecuteAsync(SocketProxySession session, SocketProxyPacket package)
    {
        try
        {
            await ExecuteAsync(session, (TPacket)package, session.PacketResponse);
        }
        catch (CloseSessionException)
        {
            await session.CloseAsync(CloseReason.ProtocolError);
        }
        catch (Exception)
        {
            await session.CloseAsync(CloseReason.ApplicationError);
        }
    }
}